package com.defu.newmall.utils;

import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StopWatch;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

@Slf4j
public class ImaMattingUtil {

    /**
     * 签名内容识别阈值 R B G三个值均低于此阈值对于的R G B的会被判定为签名内容，否则判定为背景
     *
     */

    public static final Color COLOR_THRESHOLD = new Color(100, 100, 100);

    public static void matting(String inputFilePath, String outputFilePath) throws IOException{
        matting(new File(inputFilePath), new File(outputFilePath));
    }

    private static void matting(File inputFile, File outputFile) throws IOException {
        matting(inputFile, outputFile, false);
    }

    /**
     * 抠图方法
     *
     * @param inputFile 原文件
     * @param outputFile 抠图之后的文件
     * @param isResize 是否根据签名区域对图片进行裁剪
     */
    private static void matting(File inputFile, File outputFile, boolean isResize) throws IOException {
        StopWatch stopWatch = new StopWatch();
        stopWatch.start("matting");
        BufferedImage inputImage = ImageIO.read(inputFile);

        // 创建新的BufferedImage对象作为输出结果
        BufferedImage outputImage = new BufferedImage(inputImage.getWidth(), inputImage.getHeight(), BufferedImage.TYPE_INT_ARGB);
        // 签名区域右下角横纵坐标值
        int maxX = 0 , maxY = 0;
        // 签名区域左上角横纵坐标值
        int minX = inputImage.getWidth(), minY = inputImage.getHeight();
        // 外层遍历Y轴像素
        for (int y = inputImage.getMinY(); y < inputImage.getHeight(); y++) {
            // 内层遍历X轴像素
            for (int x = inputImage.getMinX(); x < inputImage.getWidth(); x++){
                int rgb = inputImage.getRGB(x, y);
                //根据设定的阈值，判定该像素是否为签名内容
                if (isSignContent(rgb)) {
                    // 如果是签名内容，则将该像素点染成黑色
                    outputImage.setRGB(x,y, Color.BLACK.getRGB());
                    // 如果需要裁剪，则记录签名区域左上角、右上角坐标
                    if (isResize) {
                        minX = Math.min(minX, x);
                        minY = Math.min(minY, y);
                        maxX = Math.max(maxX, x);
                        maxY = Math.max(maxY, y);
                    }
                } else {
                    // 如果不是签名区域，即为背景像素，则将该像素点设置成透明
                    outputImage.setRGB(x,y,0);
                }
            }
        }
        // 如果需要裁剪，则裁取上面获取的签名区域
        if (isResize) {
            log.info("resize img: ({},{},{},{})", minX, minY, maxX, maxY);
            outputImage = outputImage.getSubimage(minX, minY, maxX - minX, maxY - minY);
        }
        // 生成图片为PNG
        ImageIO.write(outputImage, "png", outputFile);

        stopWatch.stop();
        log.info("签名图片抠图完成，耗时：{}", stopWatch.getTotalTimeMillis());
    }

    /**
     * 判定指定颜色是否是签名内容
     *
     * @param rgb 颜色值
     * @return true 是签名内容
     * false 不是签名内容
     */

    private static boolean isSignContent(int rgb) {
        Color color = new Color(rgb, true);
        // 判定透明度，如果是完全透明，则可以认为该像素点是背景
        int alpha = color.getAlpha();
        if (alpha <= 1) {
            return false;
        }
        // 如果不是透明的情况下，在判定其R G B 三值是否都小于阈值，如果都小于阈值，则认为该像素点是签名内容，否则是背景
        return color.getRed() <= COLOR_THRESHOLD.getRed() && color.getGreen() <= COLOR_THRESHOLD.getGreen() && color.getBlue() <= COLOR_THRESHOLD.getBlue();
    }

    public static void main(String[] args) throws IOException {
        matting("E:\\iworkspace\\newbee-mall\\newbee-admin\\src\\static\\qianming.png", "E:\\iworkspace\\newbee-mall\\newbee-admin\\src\\static\\res.png");
    }

}
